package com.ssy.lingxi.logistics.handler.exception;

import com.ssy.lingxi.common.response.ResponseCode;
import com.ssy.lingxi.common.response.Wrapper;
import org.springframework.core.annotation.Order;
import org.springframework.http.converter.HttpMessageConversionException;
import org.springframework.util.CollectionUtils;
import org.springframework.validation.BindException;
import org.springframework.validation.BindingResult;
import org.springframework.web.HttpMediaTypeNotSupportedException;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

/**
 * 请求参数校验异常处理类
 * @author 万宁
 * @date 2020-05-29
 * @version 2.0.0
 */
@RestControllerAdvice
@Order(1)
public class ParamCheckExceptionHandler {
    /**
     * 校验错误拦截处理
     *
     * @param exception MethodArgumentNotValidException错误类
     * @return 返回结果 错误信息
     */
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public Wrapper<?> validationBodyException(MethodArgumentNotValidException exception) {

        BindingResult result = exception.getBindingResult();

        //返回第一个错误
        String errMsg = result.getAllErrors().get(0).getDefaultMessage();

        return Wrapper.fail(ResponseCode.REQUEST_PARAM_CHECK_FAILED, errMsg);
    }

    /**
     * 参数类型转换错误拦截处理
     *
     * @param exception HttpMessageConversionException错误类
     * @return 返回结果 错误信息
     */
    @ExceptionHandler(HttpMessageConversionException.class)
    public Wrapper<?> parameterTypeException(HttpMessageConversionException exception) {
        return Wrapper.fail(ResponseCode.REQUEST_PARAM_CHECK_FAILED, exception.getMessage());
    }


    /**
     * Http请求方法不正确的异常
     * <p>例如：http post接口接收了http get请求</p>
     * @param exception
     * @return 返回结果
     */
    @ExceptionHandler(HttpRequestMethodNotSupportedException.class)
    public Wrapper<?> requestMethodException(HttpRequestMethodNotSupportedException exception) {
        return Wrapper.fail(ResponseCode.REQUEST_METHOD_NOT_SUPPORTED, ResponseCode.REQUEST_METHOD_NOT_SUPPORTED.getMessage());
    }

    /**
     * Http请求头部的Content-type设置不正确
     * @param exception
     * @return 返回结果
     */
    @ExceptionHandler(HttpMediaTypeNotSupportedException.class)
    public Wrapper<?> httpMediaTypeNotSupportedException(HttpMediaTypeNotSupportedException exception) {
        return Wrapper.fail(ResponseCode.REQUEST_CONTENT_TYPE_NOT_SUPPORTED, ResponseCode.REQUEST_CONTENT_TYPE_NOT_SUPPORTED.getMessage());
    }

    /**
     * 在Http Get查询接口使用@Valid时，不会直接获得VO中注解的message。使用下面的方法可以获得自定义的错误message
     * @param exception
     * @return 返回结果
     */
    @ExceptionHandler(BindException.class)
    public Wrapper<?> validationBindException(BindException exception) {
        String errMsg = !CollectionUtils.isEmpty(exception.getAllErrors()) ? exception.getAllErrors().get(0).getDefaultMessage() : exception.getMessage();
        return Wrapper.fail(ResponseCode.REQUEST_PARAM_CHECK_FAILED, errMsg);
    }
}
